//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#ifndef __CCAMERA_H__
#define __CCAMERA_H__

#include <display.h>
#include <camera.h>
#include <xllp_camera.h>
#include <xllp_ci.h>

//#define DEBUG_CAMERA
#ifdef DEBUG_CAMERA
#define DBGOUT(x)  x
#else
#define DBGOUT(x)
#endif

//#define _TEST_TYPE 41
#if (_TEST_TYPE == 41)      /* Test for Runtime of ISR */
#define SAMPLETIMES 50
extern UInt32 ul_DmaChYIsrTime[SAMPLETIMES];
extern UInt32 ul_DmaChCbIsrTime[SAMPLETIMES];
extern UInt32 ul_DmaChCrIsrTime[SAMPLETIMES];
#endif //_TEST_TYPE == 41

#define LCD_WIDTH  240
#define LCD_HEIGHT 320
// Sensor type
#define CAMERA_TYPE_PO1200N 1
#define CAMERA_TYPE_OV9653  2

// Quick Capture Interface FIFO
#define CIBR0_PHY 0x50000028
#define CIBR1_PHY 0x50000030
#define CIBR2_PHY 0x50000038

#define MAX_WAIT_TIME 800
#define SINGLE_DESCRIPTOR_TRANSFER_MAX  8000
#define DEFAULT_FRAMES 3
#define VIDEO_RECORD_FRAMES 4
#define MAX_FRAMES 16
#define DIGITALZOOM_MAX 4
#define GET_VIDEOBUFFER_ID(n) (n & (VIDEO_RECORD_FRAMES - 1))

#define GPIO_bit(x) (1 << ((x) & 0x1f))

// Corresponding camera.h
#define RES_QVGA  0 // CAMERA_VR_LOW
#define RES_VGA   1 // CAMERA_VR_MEDIUM
#define RES_SXGA  2 // CAMERA_VR_HIGH
// Other resolution
#define RES_QCIF  3
#if 0
#define RES_QQCIF 4
#define RES_QQVGA 5
#define RES_QCIF  6
#define RES_CIF   7
#endif

#define VIDEORES_TO_DRVRES(res) ((res == CAMERA_VR_LOW) ? RES_QCIF : RES_QVGA)

// Driver level for some functions
// Brightness: [0, 255] -> [0, 5]
#define GET_BRIGHTNESS_LEVEL(brightness) (brightness / 43)
// Contrast:   [0, 255] -> [0, 6]
#define GET_CONTRAST_LEVEL(contrast) (contrast / 37)

#define DEFAULT_BRIGHTNESS 86
#define DEFAULT_CONTRAST   111

// Frame rate
//#define FRAMERATE_PREVIEW     13
#define FRAMERATE_CAPTURE       13
#define FRAMERATE_VIDEO         15
#define FRAMERATE_VIDEO_RECORD  25

// Buffer type
#define BUFTYPE_VIDEO 0
#define BUFTYPE_STILL 1
#define BUFTYPE_PHOTO 2

typedef enum
{
    CamDrv_Status_Preview,
    CamDrv_Status_Still,
    CamDrv_Status_Video,
    CamDrv_Status_Unprepared,
    CamDrv_Status_Closed,
    CamDrv_Status_Paused,
    CamDrv_Status_Reserved
} CamDrv_Status;

typedef struct
{
    unsigned long VideoWidth;
    unsigned long VideoHeight;
    unsigned long StillWidth;
    unsigned long StillHeight;
} CamDrv_Resolution;

// Buffer address and the corresponding descriptors
#define TRANS_CHANNELS 3
typedef struct
{
    // MUST BE 8 BYTES ALIGNED
    unsigned long BufPhyAddr[MAX_FRAMES][TRANS_CHANNELS];
    unsigned long BufVirAddrKernel[MAX_FRAMES][TRANS_CHANNELS];
    unsigned long BufVirAddrUser[MAX_FRAMES][TRANS_CHANNELS];

    unsigned long DescPhyAddr[TRANS_CHANNELS];
    unsigned long DescVirAddr[TRANS_CHANNELS];

    unsigned long FrameBufSize[TRANS_CHANNELS]; // Buffer size of each FRAME
    unsigned long FrameDescNum[TRANS_CHANNELS];

    // Only used for alloc & dealloc memory, don't touch them
    unsigned int AllocBufSize;
    unsigned int AllocDescSize;
} CamDrv_DMABuffer, * PCamDrv_DMABuffer;

typedef struct
{
    int PhotoResolution;
    int VideoResolution;
    int FrameRate;
    int Zoom;
    int Brightness;
    int Contrast;
    int Sharpness;
    int WhiteBalance;
    int ColorMode;
    int SceneMode;
    int Direction;
    int Flash;
    int ISO;
    int ExposureCompensation;
    int ContinuousSnap; // Number of continuous snap
} CamDrv_AppFormat;

typedef struct
{
    char   HStartMsb;
    char   HStopMsb;
    char   VStartMsb;
    char   VStopMsb;
    char   VLsb;
    char   HLsb;
}Window,*pWindow;

typedef struct
{
    char   Com1;
    char   Com3;
    char   Com4;
    char   Com7;
}FormatControl,pFormatControl;

typedef struct
{
    char   Div;
    char   DummyMsb;
    char   DummyLsb;
    char   Banding;
}FrameRate,*pFrameRate;

// Only use part of the fileds
typedef struct
{
    Window          window;
    FrameRate       frame_rate;
    FormatControl   format_control;
    UInt16          field_exp; // USE
    UInt16          field_gain; // USE
    UInt16          field_blueg; // USE
    UInt16          field_redg; // USE
    UInt16          field_flag;
    UInt16          field_yave;
    UInt16          field_exp_bak;
    UInt16          field_gain_bak;
    UInt16          field_blueg_bak;
    UInt16          field_redg_bak;
    UInt16          field_flag_bak;
    UInt16          field_yave_bak;
} SensorSettings, *pSensorSettings;

// Context used by camera
typedef struct
{
    unsigned int SensorType;

    CamDrv_Resolution Resolution;
    int VideoResLevel;
    int StillResLevel;

    unsigned int InputFormat;
    unsigned int OutputFormat;

    unsigned int FrameRate;
    unsigned int UsedFrames; // Max Frames of DMA Transfer
    unsigned int OutFrameID; // Current Frame ID for output data
    unsigned int InFrameID; // Current Frame ID for input data

    int DMAChannels[TRANS_CHANNELS];
    CamDrv_DMABuffer StillBuffer;
    CamDrv_DMABuffer VideoBuffer;

    CamDrv_Status CaptureStatus;
    Boolean bVideo;

    // Applications directly set these formats
    CamDrv_AppFormat AppFormat;
    CamDrv_AppFormat SavedAppFormat; // For power management

    SensorSettings OmmSettings;

    OverlayFormat *pOverlay2;
} CamDrv_Context, *PCamDrv_Context;

// Camera Control Flow Functions
EXTERN_C ECode CamDrv_Install(PCamDrv_Context pCameraCxt);
EXTERN_C ECode CamDrv_Init(PCamDrv_Context pCameraCxt);
EXTERN_C void CamDrv_Quit(PCamDrv_Context pCameraCxt);
EXTERN_C ECode CamDrv_StartStillCapture(PCamDrv_Context pCameraCxt);
EXTERN_C void CamDrv_StopStillCapture(PCamDrv_Context pCameraCxt);
EXTERN_C ECode CamDrv_StartVideoCapture(PCamDrv_Context pCameraCxt);
EXTERN_C void CamDrv_StopVideoCapture(PCamDrv_Context pCameraCxt);
EXTERN_C void CamDrv_ReleaseFrames(PCamDrv_Context pCameraCxt);
EXTERN_C ECode CamDrv_SetBrightness(PCamDrv_Context pCameraCxt,
                int Brightness);
EXTERN_C ECode CamDrv_SetContrast(PCamDrv_Context pCameraCxt, int contrast);
EXTERN_C ECode CamDrv_SetSharpness(PCamDrv_Context pCameraCxt, int Sharpness);
EXTERN_C ECode CamDrv_SetWhiteBalance(PCamDrv_Context pCameraCxt,
                int WhiteBalance);
EXTERN_C ECode CamDrv_SetColorMode(PCamDrv_Context pCameraCxt,
                int ColorMode);
EXTERN_C ECode CamDrv_SetSceneMode(PCamDrv_Context pCameraCxt, int SceneMode);
EXTERN_C ECode CamDrv_SetFlash(PCamDrv_Context pCameraCxt, int Flash);
EXTERN_C ECode CamDrv_SetPhotoResolution(PCamDrv_Context pCameraCxt,
    int PhotoResolution);
EXTERN_C ECode CamDrv_SetVideoResolution(PCamDrv_Context pCameraCxt,
                int PhotoResolution);
EXTERN_C ECode CamDrv_SetDigitalZoom(PCamDrv_Context pCameraCxt, int zoom);
EXTERN_C ECode CamDrv_SetAppFormat(PCamDrv_Context pCameraCxt,
                unsigned int nID, int wParam, int lParam);
EXTERN_C ECode CamDrv_SetExposureCompensation(
                PCamDrv_Context pCameraCxt, int nExposureCompensation);
EXTERN_C ECode CamDrv_SetContinuousSnap(PCamDrv_Context pCameraCxt,
                int nCotinuousCount);
EXTERN_C ECode CamDrv_GetStillPhoto(PCamDrv_Context pCameraCxt,
                Camera_Photo* pPhoto);
EXTERN_C ECode CamDrv_GetAppFormat(PCamDrv_Context pCameraCxt,
                unsigned int nID, int *pwParam, int *plParam);
EXTERN_C ECode CamDrv_OpenHardware(PCamDrv_Context pCameraCxt);
EXTERN_C void CamDrv_CloseHardware(PCamDrv_Context pCameraCxt);
EXTERN_C void CamDrv_SaveFormat(PCamDrv_Context pCameraCxt);
EXTERN_C void CamDrv_ResumeFormat(PCamDrv_Context pCameraCxt);
EXTERN_C ECode CamDrv_StartVideoRecord(
                PCamDrv_Context pCameraCxt, IEvent ** ppOutEvent);
EXTERN_C void CamDrv_StopVideoRecord(PCamDrv_Context pCameraCxt);
EXTERN_C ECode CamDrv_GetVideoFrame(
                PCamDrv_Context pCameraCxt, Camera_ImageFrame* pFrame);

// DMA Operations Functions
EXTERN_C void DMAAllocChannel(PCamDrv_Context pCameraCxt);
EXTERN_C ECode DMAAllocBuffer(PCamDrv_Context pCameraCxt, int type);
EXTERN_C void DMAFreeBuffer(PCamDrv_Context pCameraCxt, int type);
EXTERN_C void DMAStartTransfer(PCamDrv_Context pCameraCxt);
EXTERN_C void DMAStopTransfer(PCamDrv_Context pCameraCxt);
EXTERN_C void CamDrv_SetDefaultFormat(PCamDrv_Context pCameraCxt);

// Quick Capture Interface Functions
EXTERN_C void CIInit();
EXTERN_C void CIDeInit();
EXTERN_C void CIEnable(int dma_en);
EXTERN_C int  CIDisable(int quick);
EXTERN_C void CISetMode(XLLP_CI_MODE mode, XLLP_CI_DATA_WIDTH data_width);
EXTERN_C void CISetClock(int pclk_enable, int mclk_enable,
                unsigned int mclk_khz);
EXTERN_C void CISetPolarity(int pclk_sample_falling, int hsync_active_low,
                int vsync_active_low);
EXTERN_C void CISetFIFO(unsigned int timeout,
                XLLP_CI_FIFO_THRESHOLD threshold, int fifo1_enable,
                int fifo2_enable);
EXTERN_C void CIResetFIFO();
EXTERN_C void CISetInterruptMask(unsigned int mask);
EXTERN_C void CIStartCapture(PCamDrv_Context pCameraCxt);
EXTERN_C void CIStopCapture();
EXTERN_C ECode CIPrepare(PCamDrv_Context pCameraCxt);
EXTERN_C void CISetFrameRate(XLLP_CI_FRAME_CAPTURE_RATE frate);

// Sensor Functions
EXTERN_C ECode SensorInit(PCamDrv_Context camera_context);
EXTERN_C ECode SensorSetBrightness(int level);
EXTERN_C ECode SensorSetContrast(int level);
EXTERN_C ECode SensorSetSharpness(int Sharpness);
EXTERN_C ECode SensorSetColorMode(int ColorMode);
EXTERN_C ECode SensorSetSceneMode(int SceneMode);
EXTERN_C ECode SensorGetAppResolution(PCamDrv_Context pCameraCxt,
                int resolution);
EXTERN_C ECode SensorGetResolution(PCamDrv_Context pCameraCxt,
                int resolution);
EXTERN_C ECode SensorCheckDigitalZoom(PCamDrv_Context pCameraCxt, int zoom);
EXTERN_C ECode SensorSetDigitalZoom(PCamDrv_Context pCameraCxt);
EXTERN_C ECode SensorStartCapture(PCamDrv_Context pCameraCxt);
EXTERN_C void SensorStopCapture(PCamDrv_Context pCameraCxt);

//newly added
EXTERN_C void DumpSensorRegs();
EXTERN_C void SensorViewfinderOff(void);
EXTERN_C void SensorPowerDown(int powerDown);
EXTERN_C void SensorReset();
EXTERN_C ECode SensorStartCapture(PCamDrv_Context pCameraCxt);;
EXTERN_C ECode SensorSetSaturation(int saturation);
EXTERN_C ECode SensorSetWhiteBalance(int WhiteBalance);
EXTERN_C ECode SensorSetExposureCompensation(int Level);
// GPIO Functions
EXTERN_C void GpioSetup();
EXTERN_C void GpioCloseCamera();

//I2C Functions
EXTERN_C int  I2C_write_byte(char regaddr,char val);
EXTERN_C int  I2C_read_byte(char regaddr,char *buf);

#endif//__CCAMERA_H__
